﻿// RenderUnit_Reg.cpp : 定義 DLL 應用程式的匯出函式。
//

#include <windows.h>
#include <SMART_STRING.HPP>
#include <CXXLCOMPOSITE.HPP>
#include <Sys\wifstreambuf.h>
#include <Sys\RENDERUNITREG.HPP>

using namespace std;
using namespace CxxlMan;
using namespace Cxxl3D;

// #include "stdafx.h"

#define StrPkg string_wrapper<wchar_t>

// 修改註冊表，加入符合的路徑
class ExportComposite:public cxxlComposite<StrPkg, true>
{
  virtual cxxlComposite<StrPkg,true> * cxxlFASTCALL CreateSelf(UNICODE_String idName,ISpirit *spirit) const
  {
    return new ExportComposite(idName,spirit);
  }

  virtual void cxxlFASTCALL Composite_Export(void *def, cxxlComposite<StrPkg, true> *BeExported) const
  {
    const UNICODE_String &Group = *(const UNICODE_String *)def;

    UNICODE_String dll = (StrPkg *)BeExported->GetObj();

    BeExported->SetObj(Group + L"\\" + dll); // 加入符合的路徑
  }

public:
  // Constructor
  ExportComposite(UNICODE_String idName,ISpirit *spirit)
    :cxxlObject(spirit),
    cxxlComposite(idName,spirit)
  {
  }

};


class CRenderUnitReg:public IRenderUnitReg
{
public:
  // Constructor
  CRenderUnitReg()
  {
  }

  // Destructor
  virtual ~CRenderUnitReg()
  {
  }

  virtual void cxxlFASTCALL Reg(const UNICODE_String &ExtFileName, const UNICODE_String &Group)
  {
    // 找出 RenderUnit_Reg.dll 本身(dll 檔)所在的路徑
    UNICODE_String BasePath(_MAX_PATH);
    GetModuleFileNameW(GetModuleHandleW(L"RenderUnit_Reg.dll") , (wchar_t*)(const wchar_t*)BasePath, sizeof(wchar_t)*_MAX_PATH);
    *(wcsrchr((wchar_t*)(const wchar_t*)BasePath, L'\\')) = '\0';

    UNICODE_String FindFileName = BasePath + L"\\" + Group + L"\\*." + ExtFileName;
    WIN32_FIND_DATAW FindFileData;
    HANDLE hFind = FindFirstFileW(FindFileName, &FindFileData);

    if(hFind != INVALID_HANDLE_VALUE)
    {
      while(true)
      {
        wifstreambuf wfin_buf(BasePath + L"\\" + Group + L"\\" + FindFileData.cFileName);
        if(wfin_buf.isOpen())
        {
          wistream wfin( &wfin_buf );

          Smart_Ptr<cxxlComposite<StrPkg,true> > Reg_cxxlComposite_Ptr =
          UniqueTxtCompositeImport(wfin, new ExportComposite(L"tempComposite", Spirit_Easy));
          Reg_cxxlComposite_Ptr->Export((void *)&Group);

          cxxlCM_ElementImport((cxxlComposite<StrPkg, true>*)Reg_cxxlComposite_Ptr);
        }

        if(FindNextFileW(hFind,&FindFileData) == false)
          break;
      }
    }
  }

};


extern "C" CXXL_DLLEXPORT
cxxlObject * cxxlCDECL CxxlMan_ObjectFactory(const wchar_t *ClassID, void *Arg, ISpirit *spirit)
{
  if(wcscmp(IRenderUnitReg_ClassID, ClassID) == 0)
    return new CRenderUnitReg();
  return NULL;
}



